package org.xtframe.sql;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.xtframe.common.KeyMessageFormat;
import org.xtframe.common.json.JSON2Java;
import org.xtframe.entity.SQL;
import org.xtframe.util.CommonUtil;
import org.xtframe.util.SpringUtil;
import org.xtframe.util.StringUtil;

public class SqlDataVerify {
	
	// Sql校验类型（替换、检查）
	public enum VerifyType {
		replace, check
	}
	
	private static final String BASE = "base";

	private SQL sql = null;
	
	private int count = -1;
	
	private String[] safePositions = null;
	
	private List<VerifyBase> dataVerifyList = new ArrayList<VerifyBase>();
	
	public SqlDataVerify(SQL sql, String pattern){
		this.sql = sql;
		Object list = CommonUtil.getJavaObject(pattern);
		if(JSON2Java.isArray(list)){
			for(int i=0; i<Array.getLength(list); i++){
				Map<String, Object> map = JSON2Java.optMap(Array.get(list, i));
				if(map != null){
					if(map.containsKey("vtype")){
						if(BASE.equals(map.get("vtype"))){
							if(map.containsKey("count")){
								this.count = Integer.valueOf(map.get("count").toString());
							}
							if(map.containsKey("safes")){
								Object safes = map.get("safes");
								int len = Array.getLength(safes);
								this.safePositions = new String[len];
								for(int k=0; k<len; k++)
									this.safePositions[k] = Array.get(safes, k).toString();
							}
						} else {
							SqlDataVerifyFactory sqlDataVerifyFactory = (SqlDataVerifyFactory) SpringUtil.getBean("sqlDataVerifyFactory");
							VerifyBase verifyBase = sqlDataVerifyFactory.getVerifyBase(map.get("vtype").toString());
							if(verifyBase != null) {
								verifyBase.init(map);
								dataVerifyList.add(verifyBase);	
							}
						}
					}
				}
			}
		}
	}
	
	private boolean verify(Map<String, Object> parameters, List<PreparedParameter> preparedParameters){
		if(count!=-1 && count!=parameters.size()) return false;
		for(VerifyBase verifyBase : dataVerifyList){
			if (verifyBase.getXtype() == VerifyType.replace) {
				parameters.put(verifyBase.getPosition(), verifyBase.replace(parameters, preparedParameters));
			} else if (verifyBase.getXtype() == VerifyType.check) {
				if(!verifyBase.check(parameters)) return false;
			} else {
				return false;
			}
		}
		return true;
	}
	
	public SqlData createSql(Map<String, Object> parameters){
		SqlData sqlData = new SqlData();
		List<PreparedParameter> preparedParameters = new ArrayList<PreparedParameter>();
		if(verify(parameters, preparedParameters)){
			boolean flag = true;
			for (String key : parameters.keySet()) {
				if(safePositions != null){
					flag = true;
					for(String pos : safePositions){
						if(key.equals(pos)){
							flag = false;
							break;
						}
					}
					if(!flag) continue;
				}
				parameters.put(key, StringUtil.replaceSql(StringUtil.toString(parameters.get(key), "")));
			}
			
			sqlData.setPreparedParameters(preparedParameters);
			sqlData.setSql(KeyMessageFormat.format(sql.getSqlTemplet(), parameters));
			sqlData.setResult(true);
		} else {
			sqlData.setResult(false);
		}
		return sqlData;
	}
}
